package com.example.picturestorage.bean;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.ibatis.annotations.Insert;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

@NoArgsConstructor
@Data
@Accessors(chain = true)
public class Test {

    /**
     * name : a
     * age : 2
     */

    @JsonProperty("name")
    private String name;
    @JsonProperty("age")
    private Integer age;

    public static void main(String[] args) {
        Date date = computeExpectedFinishedDate(new Date(), 7);
        System.out.println(date);
        test1();
        int compare = compare((a, b) -> {
            if (a.age > b.age) {
                return 1;
            } else if (a.getAge().equals(b.getAge())) {
                return 0;
            } else {
                return -1;
            }
        }, new Test().setAge(12), new Test().setAge(14));
        System.out.println("compare: " + compare);
        List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 5, 4, 7, 8));
        Stream<Integer> integerStream = list.stream().filter((e) -> e > 3);
        Stream<Integer> sorted = integerStream.sorted((a, b) -> {
            if (a > b) {
                return 1;
            } else if (a == b) {
                return 0;
            } else {
                return -1;
            }
        });
        int[] ints = {1, 2, 6, 5, 89, 33, 24};
        Arrays.sort(ints);
        System.out.println(Arrays.toString(ints));
//        integerStream.forEach(System.out::print);
        sorted.forEach(System.out::print);
    }

    public static Date computeExpectedFinishedDate(Date startDate, int workDays) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(Calendar.DATE, workDays);

        return calendar.getTime();
    }

    public static void test1() {
        switch (2) {
            case 1:
                System.out.println(1);
            case 2:
                System.out.println(2);
            case 3:
                System.out.println(3);
        }
    }

    public static class M {
        public static void main(String[] args) {
            ArrayList<Integer> list = new ArrayList<>(10);

            int[] ints1 = {1, 2, 3, 4, 5, 6, 7};
            int[] ints2 = {1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13};
            System.arraycopy(ints1, 2, ints2, 4, 3);
            System.out.println(Arrays.toString(ints1));
            System.out.println(Arrays.toString(ints2));


            List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
            List<? extends Class<? extends Integer>> collect = list1.stream().limit(4).map(Integer::getClass).collect(toList());
            System.out.println(collect);
            Optional<Integer> any = list1.stream().findAny();
            Integer integer = any.get();
            System.out.println(integer);
        }
    }

    public static class N {
        public static void main(String[] args) {
            ArrayList<MyStudent> myStudents = new ArrayList<>();
            myStudents.add(new MyStudent().setStuName("学生1").setMyClass(new MyClass().setClassName("301")));
            myStudents.add(new MyStudent().setStuName("学生2").setMyClass(new MyClass().setClassName("301")));
            myStudents.add(new MyStudent().setStuName("学生3").setMyClass(new MyClass().setClassName("302")));
            myStudents.add(new MyStudent().setStuName("学生4").setMyClass(new MyClass().setClassName("303")));
            myStudents.add(new MyStudent().setStuName("学生5").setMyClass(new MyClass().setClassName("301")));
            myStudents.add(new MyStudent().setStuName("学生6").setMyClass(new MyClass().setClassName("301")));
            Map<String, List<MyStudent>> collect = myStudents.stream().collect(Collectors.groupingBy(e -> e.getMyClass().getClassName()));
            collect.forEach((a,b)->{
                System.out.println(a+" "+b);
            });
        }
    }

    public static class O{
        public static void main(String[] args) {
            long time = new Date().getTime();
            System.out.println("longtime "+time);
            java.sql.Date date=new java.sql.Date(time);
            System.out.println(date.toString()+" "+date.getTime());
        }
    }

    public static class P{
        /**
         * 起始的时间戳
         */
        private final static long START_STMP = 1480166465631L;

        /**
         * 每一部分占用的位数
         */
        private final static long SEQUENCE_BIT = 12; //序列号占用的位数
        private final static long MACHINE_BIT = 5;  //机器标识占用的位数
        private final static long DATACENTER_BIT = 5;//数据中心占用的位数

        /**
         * 每一部分的最大值
         */
        private final static long MAX_DATACENTER_NUM = ~(-1L << DATACENTER_BIT);
        private final static long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT);
        private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);

        /**
         * 每一部分向左的位移
         */
        private final static long MACHINE_LEFT = SEQUENCE_BIT;
        private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
        private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;

        private final long datacenterId;  //数据中心
        private final long machineId;    //机器标识
        private long sequence = 0L; //序列号
        private long lastStmp = -1L;//上一次时间戳

        public P(long datacenterId, long machineId) {
            if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
                throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
            }
            if (machineId > MAX_MACHINE_NUM || machineId < 0) {
                throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
            }
            this.datacenterId = datacenterId;
            this.machineId = machineId;
        }

        /**
         * 产生下一个ID
         *
         * @return
         */
        public synchronized long nextId() {
            long currStmp = getNewstmp();
            if (currStmp < lastStmp) {
                throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
            }

            if (currStmp == lastStmp) {
                //相同毫秒内，序列号自增
                sequence = (sequence + 1) & MAX_SEQUENCE;
                //同一毫秒的序列数已经达到最大
                if (sequence == 0L) {
                    currStmp = getNextMill();
                }
            } else {
                //不同毫秒内，序列号置为0
                sequence = 0L;
            }

            lastStmp = currStmp;

            return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
                    | datacenterId << DATACENTER_LEFT      //数据中心部分
                    | machineId << MACHINE_LEFT            //机器标识部分
                    | sequence;                            //序列号部分
        }

        private long getNextMill() {
            long mill = getNewstmp();
            while (mill <= lastStmp) {
                mill = getNewstmp();
            }
            return mill;
        }

        private long getNewstmp() {
            return System.currentTimeMillis();
        }

        public static void main(String[] args) {
            P snowFlake = new P(2, 3);
            for (int i = 0; i < (1 << 12); i++) {
                System.out.println(snowFlake.nextId());
            }
        }
    }
    public static class Q{
        public static void main(String[] args) {
            Goods goods1 = new Goods("香蕉", 12,23);
            Goods goods2 = new Goods("苹果", 23,3);
            Goods goods3 = new Goods("葡萄", 65,6);
            ArrayList<Goods> goodsList1 = new ArrayList<>();
            goodsList1.add(goods1);
            goodsList1.add(goods2);
            goodsList1.add(goods3);
            Mechant mechant1 = new Mechant("小明水果店", goodsList1);

            Goods goods4 = new Goods("南孚电池", 100, 2);
            Goods goods5 = new Goods("南孚手电筒", 66, 1);
            ArrayList<Goods> goodsList2 = new ArrayList<>();
            goodsList2.add(goods4);
            goodsList2.add(goods5);
            Mechant mechant2 = new Mechant("南孚电池专卖店", goodsList2);

            ArrayList<Mechant> mechantList = new ArrayList<>();
            mechantList.add(mechant1);
            mechantList.add(mechant2);

            Cart cart = new Cart("user.1", mechantList);

            JSONObject o = (JSONObject)JSON.toJSON(goods1);
            System.out.println(o);
//            {"car1":{"owner":"tom","tyres":[{"name":"sd","size",16}]}}
            JSONObject parse = (JSONObject)JSONObject.parse("{\"car1\":{\"owner\":\"tom\",\"tyres\":[{\"name\":\"sd\",\"size\":16}]}}");
            System.out.println(parse);
        }
        @AllArgsConstructor
        public static class Goods implements Serializable {
            String name;
            Integer price;
            Integer amount;
        }
        @AllArgsConstructor
        public static class Mechant implements Serializable{
            String name;
            List<Goods> goodsList;
        }
        @AllArgsConstructor
        public static class Cart implements Serializable{
            String username;
            List<Mechant> mechantList;
        }
    }

    public static <T> int compare(Comparator<T> c, T t, T t2) {
        return c.compare(t, t2);
    }
}

@Data
@Accessors(chain = true)
class MyClass {
    private String className;
}

@Data
@Accessors(chain = true)
class MyStudent {
    private String stuName;
    private MyClass myClass;
}
